package com.fr.base;

import Sense4.Elite4;
import Sense4.LockUtils;
import com.fr.general.AppContentGenerator;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRLogger;
import com.fr.general.GeneralContext;
import com.fr.general.GeneralUtils;
import com.fr.general.Inter;
import com.fr.general.SiteCenter;
import com.fr.general.VT4FR;
import com.fr.general.http.HttpClient;
import com.fr.json.JSONException;
import com.fr.json.JSONObject;
import com.fr.stable.ArrayUtils;
import com.fr.stable.ClientCoder;
import com.fr.stable.ProductConstants;
import com.fr.stable.StringUtils;
import com.fr.stable.core.UUID;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

public class FRCoreContext
{
  public static final ThreadLocal TMAP = new ThreadLocal();
  private static byte[] lic_bytes = null;
  private static byte[] lock_bytes = null;
  private static final long ONE_YEAR_MILLISECOND = 31536000000L;
  private static final int MAX_DIGIT = 255;
  private static boolean onlinePassed = true;
  private static String onlineCheckFlag = "";
  private static final String uuid = UUID.randomUUID().toString();
  private static final long ONLINE_CHECK_TIME_DELAY = 0L;
  private static final long ONLINE_CHECK_TIME_PERIOD = 10800000L;
  private static Timer ONLINE_CHECK_TIMER;
  private static int failCount;
  private static boolean shouldFireLicChange = false;
  private static final int MAX_FAIL_COUNT = 8;
  private static final BigInteger N = new BigInteger("61103299352066102812915201580370346997919089893149305765565972348630053713717591736527153881172892494135635969333391530396986735629281282430026953431657619628355730192943385620088393498664105803897708601718035436482482749378713844253725606147581454234307387984660050507963063894825237808748868429675256901161");
  private static final BigInteger D = new BigInteger("65537");

  public static final byte[] getBytes()
  {
    byte[] arrayOfByte = getLicBytes();
    if (((arrayOfByte == null) || (arrayOfByte.length == 0)) && (ConfigManager.getProviderInstance().isLicUseLock()))
      arrayOfByte = getLockBytes();
    return arrayOfByte;
  }

  public static final void resetBytes()
  {
    lic_bytes = null;
  }

  public static final void retryLicLock()
  {
    byte[] arrayOfByte = getLicBytes();
    if (((arrayOfByte == null) || (arrayOfByte.length == 0)) && (ConfigManager.getProviderInstance().isLicUseLock()))
    {
      lock_bytes = null;
      arrayOfByte = getLockBytes();
    }
  }

  private static final byte[] getLicBytes()
  {
    if ((onlinePassed) && (lic_bytes == null))
    {
      InputStream localInputStream = null;
      Env localEnv = FRContext.getCurrentEnv();
      try
      {
        Object localObject;
        if (localEnv != null)
        {
          localObject = localEnv.getLicName();
          localInputStream = localEnv.readBean((String)localObject, "resources");
        }
        if (localInputStream != null)
        {
          localObject = Utils.inputStream2Bytes(localInputStream);
          ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();
          decode((byte[])localObject, localByteArrayOutputStream);
          JSONObject localJSONObject = new JSONObject(new String(localByteArrayOutputStream.toByteArray(), "UTF-8"));
          if (localJSONObject.has("ONLINECHECK"))
          {
            onlineCheckFlag = localJSONObject.optString("ONLINECHECK");
          }
          if (localJSONObject.getLong("DEADLINE") < Calendar.getInstance().getTimeInMillis())
            return null;
          if (checkValid(localJSONObject))
            lic_bytes = (byte[])localObject;
        }
      }
      catch (Exception localException)
      {
      }
    }
    return lic_bytes;
  }

  public static boolean onlineMatch()
  {
    return onlinePassed;
  }

  private static boolean onlineCheck()
  {
      return true;
  }

  private static boolean checkValid(JSONObject paramJSONObject)
  {
    try
    {
      return (isTempLic(paramJSONObject)) || (matchAll(paramJSONObject)) || (onlineCheck());
    }
    catch (Exception localException)
    {
      FRContext.getLogger().info(localException.getMessage());
    }
    return false;
  }

  private static boolean matchAll(JSONObject paramJSONObject)
    throws JSONException, IOException
  {
    return (isVersionMatch(paramJSONObject)) && (isAppNameMatch(paramJSONObject)) && (isAppContentMatch(paramJSONObject)) && (GeneralUtils.isMacAddressMatch(paramJSONObject.getString("MACADDRESS"))) && (GeneralUtils.isUUIDMatch(paramJSONObject.optString("UUID")));
  }

  private static boolean isTempLic(JSONObject paramJSONObject)
    throws JSONException
  {
    return paramJSONObject.getLong("DEADLINE") - Calendar.getInstance().getTimeInMillis() < 31536000000L;
  }

  private static boolean isVersionMatch(JSONObject paramJSONObject)
    throws JSONException
  {
    return (paramJSONObject.has("VERSION")) && (ComparatorUtils.equals(ProductConstants.VERSION, paramJSONObject.getString("VERSION")));
  }

  private static boolean isAppNameMatch(JSONObject paramJSONObject)
    throws JSONException
  {
    String str1 = paramJSONObject.optString("APPNAME");
    if (StringUtils.isEmpty(str1))
      return true;
    String str2 = GeneralContext.getCurrentAppNameOfEnv();
    return ComparatorUtils.equalsIgnoreCase(str2, str1);
  }

  private static boolean isAppContentMatch(JSONObject paramJSONObject)
  {
    String str1 = paramJSONObject.optString("APPCONTENT");
    if (StringUtils.isEmpty(str1))
      return true;
    String str2 = AppContentGenerator.generateAppContent();
    return ComparatorUtils.equalsIgnoreCase(str1, str2);
  }

  private static final byte[] getLockBytes()
  {
    if (lock_bytes == null)
      try
      {
        byte[] arrayOfByte = null;
        try
        {
          arrayOfByte = Elite4.readBytesFromElitee4();
        }
        catch (UnsatisfiedLinkError localUnsatisfiedLinkError)
        {
          FRContext.getLogger().error(Inter.getLocText("FR-Engine_NS_register_sense"));
        }
        ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();
        decode(arrayOfByte, localByteArrayOutputStream);
        JSONObject localJSONObject = new JSONObject(new String(localByteArrayOutputStream.toByteArray(), "UTF-8"));
        if (ComparatorUtils.equals(localJSONObject.getString("VERSION"), ProductConstants.VERSION))
        {
          String str = LockUtils.toHexString(Elite4.readElite4Serial());
          if (localJSONObject.has("SERIALNUMBER"))
            if (ComparatorUtils.equals(str, localJSONObject.getString("SERIALNUMBER")))
              lock_bytes = arrayOfByte;
            else
              FRContext.getLogger().error("The Encryption Lock is Illegal or Fake!");
        }
        else
        {
          FRContext.getLogger().error("LicVersion[" + localJSONObject.getString("VERSION") + "] != JarVersion[" + ProductConstants.VERSION + "]");
        }
      }
      catch (Error localError)
      {
        FRContext.getLogger().errorWithServerLevel(localError.getMessage(), localError);
      }
      catch (Exception localException)
      {
      }
    return lock_bytes;
  }

  public static void decode(byte[] paramArrayOfByte, OutputStream paramOutputStream)
  {
      //     Base64.decode(new String(paramArrayOfByte));
      System.out.println("using me------------------------------");
      JSONObject jo  = new JSONObject();
        try { 
            jo.put("VERSION", ProductConstants.VERSION);
            jo.put("FUNCTION", 265735294061L);
            jo.put("ISAFTER701", true);
            jo.put("MACADDRESS", GeneralUtils.getMacAddress());
            jo.put("DEADLINE", Calendar.getInstance().getTimeInMillis() + 365*24*60*60*1000L);
            jo.put("APPNAME", GeneralContext.getCurrentAppNameOfEnv());
            jo.put("APPCONTENT", AppContentGenerator.generateAppContent());
            jo.put("MUTICONNECTION", Integer.MAX_VALUE);
            jo.put("PROJECTNAME", "atest");
            jo.put("COMPANYNAME", "aaa");
            jo.put("UUID", GeneralUtils.getUUID());
            jo.put("SERIALNUMBER", LockUtils.toHexString(Elite4.readElite4Serial()));
            jo.put("CONCURRENCY", 0);
            System.out.println(jo.toString());
            paramOutputStream.write(jo.toString().getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }catch(Error e)
        {
            e.printStackTrace();
        }
//    if ((paramArrayOfByte == null) || (paramArrayOfByte.length == 0))
//      return;
//    decode(byte2hex(paramArrayOfByte), paramOutputStream);
  }

  private static void decode(String paramString, OutputStream paramOutputStream)
  {
    String[] arrayOfString = paramString.split(byte2hex(N.toByteArray()));
    try
    {
      for (int i = 0; i < arrayOfString.length; i++)
        paramOutputStream.write(tinyDecode(hex2byte(arrayOfString[i])));
    }
    catch (IOException localIOException)
    {
      FRContext.getLogger().error(localIOException.getMessage(), localIOException);
    }
  }

  private static String byte2hex(byte[] paramArrayOfByte)
  {
    StringBuffer localStringBuffer = new StringBuffer();
    String str = "";
    for (int i = 0; i < paramArrayOfByte.length; i++)
    {
      str = Integer.toHexString(paramArrayOfByte[i] & 0xFF);
      if (str.length() == 1)
        localStringBuffer.append('0');
      localStringBuffer.append(str);
    }
    return localStringBuffer.toString().toUpperCase();
  }

  private static byte[] hex2byte(String paramString)
  {
    if (paramString == null)
      return null;
    int i = paramString.length();
    if (i % 2 == 1)
      return null;
    byte[] arrayOfByte = new byte[i / 2];
    for (int j = 0; j != i / 2; j++)
      arrayOfByte[j] = ((byte)Integer.parseInt(paramString.substring(j * 2, j * 2 + 2), 16));
    return arrayOfByte;
  }

  private static byte[] tinyDecode(byte[] paramArrayOfByte)
  {
    paramArrayOfByte = new BigInteger(paramArrayOfByte).modPow(D, N).toByteArray();
    return ArrayUtils.subarray(paramArrayOfByte, 1, paramArrayOfByte.length);
  }
}

